package com.weifly.weistock.trade.config;

import com.weifly.weistock.core.util.WeistockUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author weifly
 * @since 2018/9/20
 */
public class CalcPriceStep {

    private double start = 0.595; // 起始价格
    private double maxPrice = 2.0; // 最大价格
    private double step = 1.0; // 网格价差
    private int groupCount = 4; // 分组数

    public static void main(String[] args) throws IOException {
        CalcPriceStep calcPriceStep = new CalcPriceStep();
        calcPriceStep.calc();
    }

    public void calc() throws IOException {
        List<PricePoint> priceList = this.initPriceList(this.start, this.maxPrice);

        this.buildGroup(priceList);

        for(PricePoint point : priceList){
            System.out.println(point.desc());
        }

        this.generateExcel(priceList);
    }

    private List<PricePoint> initPriceList(double min, double max){
        List<PricePoint> priceList = new ArrayList<>();
        double curr = min;
        while(curr<=max){
            PricePoint pricePoint = new PricePoint();
            pricePoint.price = curr;
            priceList.add(pricePoint);
            curr = WeistockUtils.add(curr, 0.001);
        }
        return priceList;
    }

    private void buildGroup(List<PricePoint> priceList){
        PricePoint currPoint = null; // 当前价点
        List<PricePoint> currPointList = new ArrayList<>(); // 当前价点集合
        PricePoint[] groupPoints = new PricePoint[this.groupCount]; // 每组当前的价点

        Iterator<PricePoint> iter = priceList.iterator();
        // 查找开始值
        while(iter.hasNext()){
            PricePoint point = iter.next();
            if(point.price==this.start){
                currPoint = point;
                break;
            }
        }
        if(currPoint==null){
            throw new RuntimeException("没有找到起始值, start="+this.start);
        }else{
            currPointList.add(currPoint);
        }

        // 查找下一个满足的值
        while(iter.hasNext()){
            PricePoint point = iter.next();
            double nowDiff = WeistockUtils.subtract(point.price, currPoint.price);
            double nowStep = WeistockUtils.divide(WeistockUtils.multi(nowDiff, 100), currPoint.price);
            if(nowStep>=this.step){
                // 满足条件
                this.updateGroupStatus(currPointList, groupPoints);
                currPoint = point;
                currPointList.clear();
                currPointList.add(currPoint);
            }else{
                // 不满足
                currPointList.add(point);
            }
        }
    }

    private void updateGroupStatus(List<PricePoint> currPointList, PricePoint[] groupPoints){
        int priceSize = currPointList.size();
        int groupSize = groupPoints.length;
        if(priceSize<groupSize){
            throw new RuntimeException("不够分配");
        }
        int param1 = priceSize/groupSize;
        int param2 = priceSize%groupSize;

        int idx = 0;
        for(int i=0;i<groupSize;i++){
            PricePoint currPoint = currPointList.get(idx);
            PricePoint prePoint = groupPoints[i];
            // 更新point
            currPoint.group = (i+1);
            if(prePoint!=null){
                double nowDiff = WeistockUtils.subtract(currPoint.price, prePoint.price);
                double nowStep = WeistockUtils.divide(WeistockUtils.multi(nowDiff, 100), prePoint.price);
                currPoint.diff = nowDiff;
                currPoint.step = nowStep;
            }
            groupPoints[i] = currPoint;
            // 更新idx
            idx += param1;
            if((i+param2)>=groupSize){
                idx++;
            }
        }
    }

    private void generateExcel(List<PricePoint> priceList) throws IOException {
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("pricePoint");
        int rowIndex = 0;
        // 表头
        XSSFRow headRow = sheet.createRow(rowIndex++);
        this.createStringCell(headRow, 0, "价格");
        this.createStringCell(headRow, 1, "分组");
        this.createStringCell(headRow, 2, "价差");
        this.createStringCell(headRow, 3, "上涨幅度");

        // 数据
        for(PricePoint point : priceList){
            XSSFRow dataRow = sheet.createRow(rowIndex++);
            this.createNumberCell(dataRow, 0, point.price);
            if(point.group!=0){
                this.createNumberCell(dataRow, 1, point.group);
            }
            if(point.diff!=0){
                this.createNumberCell(dataRow, 2, point.diff);
            }
            if(point.step!=0){
                this.createNumberCell(dataRow, 3, point.step);
            }
        }

        try(FileOutputStream outputStream = new FileOutputStream("D:\\price.xlsx")){
            workbook.write(outputStream);
        }
    }

    private void createStringCell(XSSFRow headRow, int columnIndex, String value){
        headRow.createCell(columnIndex, Cell.CELL_TYPE_STRING).setCellValue(value);
    }

    private void createNumberCell(XSSFRow headRow, int columnIndex, double value){
        headRow.createCell(columnIndex, Cell.CELL_TYPE_NUMERIC).setCellValue(value);
    }

    private class PricePoint{
        double price; // 价格
        int group; // 所属分组
        double diff; // 价差
        double step; // 上涨幅度

        public String desc(){
            StringBuffer sb = new StringBuffer();
            sb.append("price=").append(this.price);
            sb.append(", group=").append(this.group);
            sb.append(", diff=").append(this.diff);
            sb.append(", step=").append(this.step);
            return sb.toString();
        }
    }
}

